package com.siyoumi.app.modules.user.service;

import com.siyoumi.app.entity.*;
import com.siyoumi.app.modules.user.vo.*;
import com.siyoumi.app.service.SysSaleClientService;
import com.siyoumi.app.service.SysSaleRecordService;
import com.siyoumi.app.service.SysSaleService;
import com.siyoumi.component.XApp;
import com.siyoumi.component.XBean;
import com.siyoumi.component.XSpringContext;
import com.siyoumi.component.http.InputData;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.config.SysConfig;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.mybatispuls.JoinWrapperPlus;
import com.siyoumi.service.IWebService;
import com.siyoumi.util.XDate;
import com.siyoumi.util.XReturn;
import com.siyoumi.util.XStr;
import com.siyoumi.validator.XValidator;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

//分销员
@Slf4j
@Service
public class SvcSysSale
        implements IWebService {
    static public SvcSysSale getBean() {
        return XSpringContext.getBean(SvcSysSale.class);
    }

    static public SysSaleService getApp() {
        return SysSaleService.getBean();
    }

    /**
     * 生效
     *
     * @param entity
     * @return
     */
    public XReturn valid(SysSale entity) {
        if (entity == null) {
            return EnumSys.ERR_VAL.getR("帐号ID异常");
        }
        if (entity.getSale_state() != 1) {
            return EnumSys.ERR_VAL.getR("帐号已失效");
        }

        return EnumSys.OK.getR();
    }

    /**
     * 根据uid获取分销员
     */
    public SysSale getEntitySaleByUid(String uid) {
        return XHttpContext.getAndSetData(uid, k -> {
            JoinWrapperPlus<SysSale> query = listQuery();
            query.eq("sale_uid", uid);
            return getApp().first(query);
        });
    }

    /**
     * 获取客户uid获取分销员
     *
     * @param clientUid
     */
    public SysSale getEntitySale(String clientUid) {
        JoinWrapperPlus<SysSale> query = listQuery();
        query.join(SysSaleClient.table(), "sale_uid", "sacl_sale_uid");
        query.eq("sacl_client_uid", clientUid);
        return getApp().first(query);
    }

    public JoinWrapperPlus<SysSale> listQuery() {
        return listQuery(InputData.getIns());
    }

    /**
     * select
     *
     * @return query
     */
    public JoinWrapperPlus<SysSale> listQuery(InputData inputData) {
        String uid = inputData.input("uid");
        String state = inputData.input("state");
        String level = inputData.input("level");

        JoinWrapperPlus<SysSale> query = getApp().join();
        query.eq("sale_x_id", XHttpContext.getX());

        if (XStr.hasAnyText(uid)) { //uid
            query.eq("sale_uid", uid);
        }
        if (XStr.hasAnyText(level)) { //等级
            query.eq("sale_level", level);
        }
        if (XStr.hasAnyText(state)) { //审核状态
            query.eq("sale_state", state);
        }

        return query;
    }

    /**
     * 获取分销关系
     *
     * @param clientUid
     */
    public SysSaleClient getEntityClient(String clientUid) {
        return SysSaleClientService.getBean().first(listClientQuery(clientUid));
    }

    public JoinWrapperPlus<SysSaleClient> listClientQuery(String clientUid) {
        JoinWrapperPlus<SysSaleClient> query = listClientQuery(InputData.getIns());
        query.eq("sacl_client_uid", clientUid);

        return query;
    }

    /**
     * 绑定关系
     *
     * @return query
     */
    public JoinWrapperPlus<SysSaleClient> listClientQuery(InputData inputData) {
        String saleUid = inputData.input("sale_uid");

        JoinWrapperPlus<SysSaleClient> query = SysSaleClientService.getBean().join();
        query.eq("sacl_x_id", XHttpContext.getX());

        if (XStr.hasAnyText(saleUid)) { //分销员
            query.eq("sacl_sale_uid", saleUid);
        }

        return query;
    }

    public JoinWrapperPlus<SysSaleRecord> listRecordQuery(String abType) {
        InputData inputData = InputData.getIns();
        inputData.put("ab_type", abType);
        return listRecordQuery(inputData);
    }

    public JoinWrapperPlus<SysSaleRecord> listRecordQuery() {
        JoinWrapperPlus<SysSaleRecord> query = listRecordQuery(InputData.getIns());
        return query;
    }

    /**
     * 入帐明细
     *
     * @return query
     */
    public JoinWrapperPlus<SysSaleRecord> listRecordQuery(InputData inputData) {
        String uid = inputData.input("uid");
        String dateBegin = inputData.input("date_begin");
        String dateEnd = inputData.input("date_end");
        String abType = inputData.input("ab_type", "all");

        JoinWrapperPlus<SysSaleRecord> query = SysSaleRecordService.getBean().join();
        query.eq("srec_x_id", XHttpContext.getX());

        if (XStr.hasAnyText(uid)) { //分销员
            query.eq("srec_uid", uid);
        }
        if (XStr.hasAnyText(abType)) { //加减
            if ("all".equals(abType)) {
                query.in("srec_ab_type", "+", "-");
            } else {
                query.eq("srec_ab_type", abType);
            }
        }

        if (XStr.hasAnyText(dateBegin) && XStr.hasAnyText(dateEnd)) { //创建时间
            LocalDateTime b = XDate.parse(dateBegin);
            LocalDateTime e = XDate.parse(dateEnd);
            query.between("srec_create_date", b, e);
        }

        return query;
    }

    /**
     * 申请分销员
     *
     * @param vo
     */
    public XReturn save(VoSale vo) {
        InputData inputData = InputData.getIns();

        SysSale entity = getApp().getEntity(vo.getSale_id());
        if (entity != null) {
            inputData.put("id", vo.getSale_id());
        }

        List<String> ignoreField = new ArrayList<>();
        if (inputData.isAdminEdit()) {
            ignoreField.add("srec_uid");
            ignoreField.add("sale_state");
        }

        return XApp.getTransaction().execute(status -> {
            XReturn r = getApp().saveEntity(inputData, vo, false, ignoreField);
            return r;
        });
    }

    /**
     * 删除
     */
    @SneakyThrows
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn delete(List<String> ids) {
        XReturn r = XReturn.getR(0);

        getApp().delete(ids);

        return r;
    }

    /**
     * 删除
     */
    @SneakyThrows
    @Transactional(propagation = Propagation.MANDATORY)
    public XReturn deleteClient(List<String> ids) {
        XReturn r = XReturn.getR(0);

        SysSaleClientService.getBean().delete(ids);

        return r;
    }

    /**
     * 审核
     *
     * @param vo
     */
    @Transactional(rollbackFor = Exception.class)
    public XReturn audit(VoSaleAudit vo) {
        List<SysSale> list = getApp().get(vo.getIds());
        if (list.isEmpty()) {
            return EnumSys.OK.getR();
        }

        for (SysSale entity : list) {
            //if (entity.getSale_state() != 0) {
            //    continue;
            //}

            SysSale entityUpdate = new SysSale();
            entityUpdate.setSale_id(entity.getKey());
            entityUpdate.setSale_state(vo.getEnable());
            entityUpdate.setSale_state_date(XDate.now());
            getApp().updateById(entityUpdate);
        }

        return EnumSys.OK.getR();
    }


    /**
     * 绑定客户
     *
     * @param vo
     */
    public XReturn bindClient(VoSaleBindClient vo) {
        SysSale entitySale = getApp().getEntity(vo.getSale_uid());
        XValidator.isNull(entitySale, "分销员uid异常");
        XValidator.err(valid(entitySale));

        if (!"".equals(entitySale.getSale_type())) {
            return XReturn.getR(20117, "类型异常");
        }

        if (vo.getSale_uid().equals(vo.getClient_uid())) {
            return XReturn.getR(20107, "自己不能绑定自己");
        }

        SysSaleClient entityClient = getEntityClient(vo.getClient_uid());
        if (entityClient != null) {
            if (!entityClient.getSacl_sale_uid().equals(vo.getSale_uid())) {
                return XReturn.getR(20117, "已绑定其他人");
            } else { //已绑定
                return EnumSys.OK.getR();
            }
        }

        SysSaleClient entityNew = new SysSaleClient();
        entityNew.setSacl_x_id(XHttpContext.getX());
        entityNew.setSacl_sale_uid(vo.getSale_uid());
        entityNew.setSacl_client_uid(vo.getClient_uid());
        entityNew.setAutoID();
        SysSaleClientService.getBean().save(entityNew);

        return EnumSys.OK.getR();
    }

    /**
     * 入账出帐
     */
    public SysSaleRecord addRecord(VoSaleAddRecord vo) {
        String abType = vo.getSrec_num().compareTo(BigDecimal.ZERO) > 0 ? "+" : "-";

        SysSaleRecord entity = new SysSaleRecord();
        XBean.copyProperties(vo, entity);
        entity.setSrec_desc(XStr.maxLen(vo.getSrec_desc(), 100));
        entity.setSrec_ab_type(abType);
        entity.setSrec_x_id(XHttpContext.getX());
        entity.setSrec_id(XApp.getStrID("S"));

        XApp.getTransaction().execute(status -> {
            boolean save = SysSaleRecordService.getBean().save(entity);
            if (vo.getUpdateLeft()) { //更新余额
                updateMoneyLeft(vo.getSrec_uid(), false);
                updateMoneyLeft(vo.getSrec_uid(), true);
            }

            return save;
        });

        return entity;
    }

    static protected BigDecimal getMoneyMax() {
        return SvcSaleSetting.getBean().getSettingTxt00().getGet_money_max();
    }

    static protected BigDecimal getMoneyMin() {
        return SvcSaleSetting.getBean().getSettingTxt00().getGet_money_min();
    }

    static protected BigDecimal getMoneyMaxDay1() {
        return SvcSaleSetting.getBean().getSettingTxt00().getGet_money_max_day1();
    }

    /**
     * 提现
     */
    @Transactional(rollbackFor = Exception.class)
    public XReturn getMoney(VoSaleGetMoney vo) {
        SysSale entitySale = getEntitySaleByUid(vo.getUid());
        if (entitySale == null) {
            return XReturn.getR(20321, "用户没权限提现");
        }
        XValidator.err(valid(entitySale));
        //
        if (XStr.isNullOrEmpty(vo.getTrue_name())) {
            return XReturn.getR(20331, "用户未设置正真姓名，无法提现");
        }
        if (!vo.getIsStore()) { //主播提现
            if (vo.getMoney().compareTo(getMoneyMax()) > 0 || vo.getMoney().compareTo(getMoneyMin()) < 0) {
                return XReturn.getR(20341, XStr.format("提现金额{0}-{1}", getMoneyMin().toString(), getMoneyMax().toString()));
            }
            //1天提现累积提现
            {
                JoinWrapperPlus<SysSaleRecord> query = listRecordQuery("+");
                query.eq("srec_uid", entitySale.getSale_uid())
                        .between("srec_create_date", XDate.today(), XDate.today().plusDays(1).minusSeconds(1))
                ;
                BigDecimal getNum = SysSaleRecordService.getBean().sum(query, "srec_num");
                if (getNum.add(vo.getMoney()).compareTo(getMoneyMaxDay1()) > 0) {
                    XReturn r = XReturn.getR(20345, "提现累积已超当天最大值，" + getMoneyMaxDay1());
                    r.setData("money_max_day1", getMoneyMaxDay1());
                    return r;
                }
            }
        }
        BigDecimal leftMoney = updateMoneyLeft(vo.getUid(), false);
        if (vo.getMoney().compareTo(leftMoney) > 0) {
            return XReturn.getR(20351, "用户提现余额不足");
        }

        String key = XDate.toS().toString();
        VoSaleAddRecord data = VoSaleAddRecord.of(key
                , vo.getUid()
                , vo.getMoney().negate()
                , "提现"
                , vo.getApp_id()
                , vo.getUid());
        SysSaleRecord entityRecord = SvcSysSale.getBean().addRecord(data);

        String openid = null;
        if (!vo.getIsStore()) {
            openid = SvcSysUser.getBean().getOpenid(vo.getUid());
        }

        //新建提现记录
        VoCorpPaySave corpPayData = VoCorpPaySave.of(entityRecord.getKey()
                , vo.getUid()
                , openid
                , XApp.decimalToFee(vo.getMoney())
                , vo.getTrue_name()
                , vo.getApp_id()
                , entityRecord.getKey()
        );
        corpPayData.setCorppayq_bank_no(vo.getBank_no());
        corpPayData.setCorppayq_bank_code(vo.getBank_code());

        corpPayData.setCorppayq_desc("提现");
        SysCorpPay entityCorpPay = SvcSysCorpPay.getBean().save(corpPayData);
        XReturn r = XReturn.getR(0);
        r.setData("entity", entityCorpPay);

        return r;
    }

    /**
     * 获取余额
     *
     * @param uid
     */
    public BigDecimal getMoneyLeft(String uid) {
        SysSale entity = getApp().getEntity(uid);
        if (entity == null) {
            return BigDecimal.ZERO;
        }

        return entity.getSale_money_left();
    }

    /**
     * 更新用户余额
     *
     * @param uid
     */
    public BigDecimal updateMoneyLeft(String uid, boolean updateTotal) {
        InputData inputData = InputData.getIns();
        if (updateTotal) {
            inputData.put("ab_type", "+");
        }

        JoinWrapperPlus<SysSaleRecord> query = listRecordQuery(inputData);
        query.eq("srec_uid", uid);

        BigDecimal money = SysSaleRecordService.getBean().sum(query, "srec_num");

        SysSale entity = getApp().getEntity(uid);
        if (entity == null) {
            XValidator.err(EnumSys.ERR_VAL.getR("not find sale"));
        }
        SysSale update = new SysSale();
        update.setSale_id(entity.getKey());
        if (updateTotal) {
            update.setSale_money_total(money);
        } else {
            update.setSale_money_left(money);
        }

        getApp().updateById(update);

        return money;
    }
}
